package minuy.android.minuygradienter.View;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import minuy.android.minuygradienter.R;

public class LedMpu6050View extends View {

    final String TAG = "自定义界面";

    private Context mContext;

    //控件大小（画布的大小）
    private float mWidth = 0;
    private float mHeight = 0;

    //画笔，普通的，画LED的
    private Paint paint,paintLed;

    //横滚角，俯仰角，偏航角
    private int posRoll,posPitch,yaw;
    //限制框的两个坐标
    private  int maxRoll,maxPitch,minRoll,minPitch;
    //极坐标系的极径ρ和极角θ
    private double p,o;
    //LED灯PWM，表示明灭，255：亮，0：灭
    private int[] ledPower = new int[25];
    //圆弧中心（位置）表示圆弧位置
    private int indexA = 0;
    //圆弧角度（长度）表示圆弧长度
    private int longA = 0;

    //Led的总数
    final int allLed = 25;
    //LED灯的排列半径ρ
    final float ledP = 320.0f;
    //LED的步进角度
    final float ledO = 360.0f/(float) allLed;

    //构造函数
    public LedMpu6050View(Context context) {
        super(context);
        mContext = context;
        InitView(null, 0);
    }
    //构造函数
    public LedMpu6050View(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        InitView(attrs, 0);
    }
    //构造函数
    public LedMpu6050View(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
        InitView(attrs, defStyle);
    }

    private void InitView(AttributeSet attrs, int defStyle){
        paint = new Paint();
        paint.setColor(ContextCompat.getColor(mContext,R.color.purple_700));//设置颜色
        paint.setStyle(Paint.Style.STROKE);//设置风格
        paint.setStrokeWidth(5f);//设置宽度

        paintLed = new Paint();
        paintLed.setColor(ContextCompat.getColor(mContext,R.color.white));
        paintLed.setStyle(Paint.Style.FILL);
        paintLed.setStrokeWidth(1f);//设置宽度

        for (int v:ledPower) {
            v = 0;
        }
    }

    //最终尺寸确定后调用
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mHeight = h;
        mWidth = w;
    }

    //绘图
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawAxises(canvas);//画坐标轴
        drawTag(canvas);//画浮点
        //drawTagMax(canvas);//画限制框
        //darwText(canvas);//画文本
        drawYaw(canvas);//画方向
        drawLed(canvas);//画LED
        drawA(canvas);//画圆弧
    }

    /**
     * 画圆弧
     * @param canvas
     */
    private void drawA(Canvas canvas) {
        paint.setColor(ContextCompat.getColor(mContext,R.color.red_old));
        RectF rectF = new RectF();
        rectF.right = 360;
        rectF.left = -360;
        rectF.top = -360;
        rectF.bottom = 360;
        canvas.drawArc(rectF,indexA-longA,40,false,paint);
    }

    /**
     * 画文字，调试用
     * @param canvas
     */
    private void darwText(Canvas canvas){
        paint.setStrokeWidth(1);
        paint.setTextSize(60);
        paint.setColor(ContextCompat.getColor(mContext,R.color.white));
        canvas.drawText("("+yaw+","+maxPitch+") ("+minRoll+","+minPitch+")",-mWidth/2,-400,paint);
        canvas.drawText("("+posRoll+","+posPitch+") ("+String.format("%.2f", p)+","+String.format("%.2f", o)+")",-mWidth/2,470,paint);

        paint.setStrokeWidth(5);
    }

    /**
     * 画航向角圆弧
     * @param canvas
     */
    private void drawYaw(Canvas canvas){
        paint.setColor(ContextCompat.getColor(mContext,R.color.purple_700));
        RectF rectF = new RectF();
        rectF.right = 400;
        rectF.left = -400;
        rectF.top = -400;
        rectF.bottom = 400;
        canvas.drawArc(rectF,yaw-15,30,false,paint);
    }

    /**
     * 画坐标轴
     * @param canvas
     */
    private void drawAxises(Canvas canvas){
        paint.setColor(ContextCompat.getColor(mContext,R.color.white_old));
        //移动画布到中心位置
        canvas.translate(mWidth/2,mHeight/2);
        //画轴
        canvas.drawLine(0,0,0,mHeight/2,paint);
        canvas.drawLine(0,0,mWidth/2,0,paint);
        canvas.drawLine(0,0,0,-mHeight/2,paint);
        canvas.drawLine(0,0,-mWidth/2,0,paint);
    }

    /**
     * 画目标点
     * @param canvas
     */
    private void drawTag(Canvas canvas){
        paint.setColor(ContextCompat.getColor(mContext,R.color.red));
        //竖轴
        canvas.drawCircle(0,posPitch,4,paint);
        //横轴
        canvas.drawCircle(posRoll,0,4,paint);
        //目标浮点
        canvas.drawCircle(posRoll,posPitch,12,paint);
    }


    /**
     * 根据加速度仪器设置视图
     * @param rollAngle 横滚角
     * @param pitchAngle 俯仰角
     * @param azimuth 航向角
     */
    public void setAngle(float rollAngle, float pitchAngle, float azimuth) {

        //从值转换成度数
        yaw = (int)toDegrees(azimuth);
        posPitch = ((int)toDegrees(pitchAngle));
        posRoll =  ((int)toDegrees(rollAngle));

        //锁定角度（垂直）
        if(posPitch>90){
            posPitch = 90;
        }else if(posPitch<-90){
            posPitch = -90;
        }
        //锁定角度（水平）
        if(posRoll>90){
            posRoll = 180 - posRoll;
        }else if(posRoll<-90){
            posRoll = -180 - posRoll;
        }

        //缩放到360并反转（默认是高处）
        posPitch*=-4;
        posRoll*=-4;

        //确定最大值（画限制框用）
        maxPitch = maxPitch>posPitch?maxPitch:posPitch;
        maxRoll = maxRoll>posRoll?maxRoll:posRoll;
        //确定最小值（画限制框用）
        minPitch = minPitch<posPitch?minPitch:posPitch;
        minRoll = minRoll<posRoll?minRoll:posRoll;

        //直角坐标系
        //横轴x
        float x = posRoll;
        //纵轴y
        float y = posPitch;

        //转换到极坐标系
        //计算极径ρ
        p = Math.pow((x*x)+(y*y),0.5);
        //计算极角θ
        if(x!=0) {
            o = toDegrees(Math.atan2(y, x));
        }

        //重新初始化灯
        for(int i=0;i<ledPower.length;i++){
            ledPower[i] = 0;
        }

        //根据ρ计算灯点亮的数量
        int ledNumber = (int)(((1.0f/360.0f)*Math.pow(p-360f,2))*25.0/((1.0f/360.0f)*Math.pow(0-360f,2)));
        //根据θ计算中心灯位置
        int ledIndex = (int)(o/14.4f)+1;

        //根据数量计算每盏灯的亮度
        for(int i=(int)(-ledNumber/2.0);i<(int)(ledNumber/2.0);i++){
            if(ledNumber<19) {
                //255cos((0.12+((26-20)*0.005))x)   数量：20
                //函数图像：https://zuotu.91maths.com/#W3sidHlwZSI6MCwiZXEiOiIyNTVjb3MoKDAuMTIrKCgyNi0yMCkqMC4wMDUpKXgpIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTEyNS40ODgxNzQ0Njg2NTEyMSIsIjExMC45ODA0NDc5OTIzMDk3MyIsIjMzLjg3ODQwMjI1NDQzMjQxNiIsIjE3OS4zOTc1NTQ1MzgxMDA4OCJdLCJncmlkIjpbIjEiLCIxIl19XQ==
                ledPower[getLoop(ledIndex, ledPower.length, i)] = (int) (255 * Math.cos((0.12 + ((26 - ledNumber) * 0.005)) * i));
            }else {
                //(((-181/25)*20)/128)x^2+255    数量：20
                //函数图像：https://zuotu.91maths.com/#W3sidHlwZSI6MCwiZXEiOiIoKCgtMTgxLzI1KSoyMCkvMTI4KXheMisyNTUiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMjMuMDYwNjAyMTc0Mzk2NTgiLCIyNi41MzA0NjIyNzg3MjgzMTUiLCItMTEuMTIyNjk3MTUzMzg1OTMyIiwiMTkuMzk0ODgwOTcxNjE0MDUiXSwiZ3JpZCI6WyIxIiwiMSJdfV0=
                ledPower[getLoop(ledIndex, ledPower.length, i)] = (int) ((((-181.0 / 25.0) * (float) ledNumber) / 128.0) * (float) i * (float) i + 255);
            }
        }

        //保证至少有一个灯亮
        if(ledNumber<=1){
            ledPower[getLoop(ledIndex,ledPower.length,0)] = 255;
        }

        //在一个范围内认为是水平的
        if(p<5){
            char val;
            if(p<2){
                val = 0xff;
            }else {
                val = 0xc7;
            }

            for (int i = 0; i < ledPower.length; i++) {
                ledPower[i] = val;
            }
        }

        //圆弧计算
        longA = (int)(14.4f*ledNumber);
        indexA = (int)(o+7.2f*ledNumber);

        //让系统画画
        invalidate();
    }

    /**
     * 画LED小灯
     * @param canvas
     */
    private void drawLed(Canvas canvas) {
        int i = 0;

        //画一个圆圈
        while(i<allLed){
            //从角度值转换成角度
            double de = i*ledO*PI/180.0f;

            //转换成直角坐标系
            float x = (float) (ledP*Math.cos(de));
            float y = (float) (ledP*Math.sin(de));

            //调整灯的亮度（通过透明度调整）
            paintLed.setColor(Color.argb(ledPower[i],ledPower[i],ledPower[i],ledPower[i]));
            //画圆（小灯）
            canvas.drawCircle(x,y,20,paintLed);

            //打印日志
            Log.d(TAG, "drawLed: ledPower["+i+"]:"+ledPower[i]);

            //递增
            i++;
        }
    }

    /**
     * 循环获取数组，比如index = -1，i = 0，那么就取size返回
     * @param index 索引开始
     * @param size 大小
     * @param i 索引偏移
     * @return 真实索引
     */
    private int getLoop(int index,int size,int i){
        int curIndex = index+i;
        if(curIndex<size&&curIndex>=0){

        }else if(curIndex>=size){
             curIndex-=size;
        }else if(curIndex<0){
             curIndex+=size;
        }

        if(curIndex>=0 &&curIndex<size) {
            return curIndex;
        }else{
            return 0;
        }
    }

    //π常量
    public static final double PI = 3.14159265358979323846;

    /**
     * 把值转换成角度
     * @param angrad 值
     * @return 对应的角度
     */
    public static double toDegrees(double angrad) {
        return angrad * 180.0 / PI;
    }


    /**
     * 画限制框
     * @param canvas
     */
    private void drawTagMax(Canvas canvas){
        paint.setColor(ContextCompat.getColor(mContext,R.color.teal_a));

        Rect rect = new Rect();
        rect.right = maxRoll;
        rect.left = minRoll;
        rect.top = minPitch;
        rect.bottom = maxPitch;
        canvas.drawRect(rect,paint);
    }
}
